from datetime import datetime
from rest_framework.viewsets import ViewSet
from django.db import transaction
from rest_framework import serializers, request
from django_redis import get_redis_connection

from course.models import Course, CourseExpire
from order.models import Order, OrderDetail
from rest_framework import request

class OrderModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = ("id", "order_number", "pay_type","real_price","total_price")

        extra_kwargs = {
            "id": {"read_only": True},
            "order_number": {"read_only": True},
            "pay_type": {"write_only": True},
            "real_price": {"write_only": True},
            "total_price": {"write_only": True},
        }

    def validate(self, attrs):
        # 对数据进行验证
        pay_type = attrs.get("pay_type")
        try:
            Order.pay_choices[pay_type]
        except Order.DoesNotExist:
            raise serializers.ValidationError("您当前选择的支付方式不允许")
        return attrs

    # 重写create方法,生成订单和订单详情
    def create(self, validated_data):
        print("获取的属性值------获取的属性值")
        print(validated_data.get("pay_type"))
        print(validated_data.get("total_price"))


        redis_connection = get_redis_connection("cart")
        incr = redis_connection.incr("order")
        # 通过context获取到request对象
        user_id = self.context["request"].user.id
        # 生成唯一的订单号 一般组合 时间戳,用户id,随机字符串
        order_number = datetime.now().strftime("%Y%m%d%H%M%S") + "%06d" % user_id + "%06d" % incr
        print("订单编号为")
        print(order_number)

        # 生成订单
        order = Order.objects.create(
            order_title="百知在线课程订单",
            total_price=100,
            real_price=100,
            order_number=order_number,  # 订单编号,上面生成的
            order_status=0,  # 订单状态,默认未支付
            pay_type=validated_data.get("pay_type"),  # 支付方式,支付类型
            credit=0,  # 积分
            coupon=0,
            order_desc="优惠力度空前绝后,抓紧抢购哦,亲们",  # 订单描述
            user_id=user_id,
        )


        #开启事务,有问题,回退
        with transaction.atomic():

            #记录事务回滚的点,如果失败,从这边开始回滚
            rollback_id = transaction.savepoint()

            # 生成订单详情,
            # 获取从购物车所勾选的商品
            # 获取当前登录用户的购物车中的所有商品
            cart_list = redis_connection.hgetall("cart_%s" % user_id)
            select_list = redis_connection.smembers("selected_%s" % user_id)

            for course_id_byte, expire_id_byte in cart_list.items():
                course_id = int(course_id_byte)
                expire_id = int(expire_id_byte)  # 过期时间
                # 商品信息
                print("商品")
                print(course_id)
                print(expire_id)
                #判断商品id是否在已经勾选的列表中
                if course_id_byte in select_list:
                    try:
                        course = Course.objects.get(pk=course_id)
                    except Course.DoesNotExist:
                        # continue
                        #课程不存在则不再进行订单详情的生成,已经生成好的订单表也不再保存
                        transaction.savepoint_rollback(rollback_id)
                        return serializers.ValidationError("对不起,当前商品不存在,事务已回滚")

                    # 如果有效期的id大于0,则需要计算商品的价格,id不大于0,代表永久有效,需要一个默认值
                    original_price = course.price
                    expire_text = "永久有效"
                    try:
                        if expire_id > 0:
                            course_expire = CourseExpire.objects.get(id=expire_id)
                            # 对应的价格
                            original_price = course_expire.price
                            expire_text = course_expire.expire_text
                    except CourseExpire.DoesNotExist:
                        pass
                    # 根据已经勾选的商品的对应的有效期的价格去计算勾选商品的最终价格
                    real_expire_price = course.real_expire_price(expire_id)

                    # 生成订单详情
                    try:
                        OrderDetail.objects.create(
                            order=order,
                            course=course,
                            expire=expire_id,
                            price=original_price,
                            real_price=real_expire_price,
                            discount_name=course.discount_name,
                        )

                    except:
                        transaction.savepoint_rollback(rollback_id)   #事务回滚
                        raise serializers.ValidationError("订单生成失败")

                    # 计算订单的总价
                    order.total_price += float(original_price),
                    order.real_price += float(real_expire_price),
                order.save()
            return order
